package org.jsbd.boss.common;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsbd.boss.annotation.ExportExcelAnnotation;
import org.springframework.web.multipart.MultipartFile;

/**
 * 读excel文件
 * 
 * @author zhangmingjun
 *
 */
public class ImportExcel<T> {

	public static final String XLS = "xls";
	public static final String XLSX = "xlsx";
	public static final String STRING_EMPTY = "";

	public static <T> List<T> readExcel(MultipartFile file, Class<?> clazz)
			throws IOException, IllegalArgumentException, IllegalAccessException {
		if (file == null || file.getOriginalFilename() == null) {
			return null;
		}
		// String fileName = file.getOriginalFilename();
		// if (fileName.endsWith(XLS)) {
		// return readXls(file, clazz);
		// } else if (fileName.endsWith(XLSX)) {
		// return readXlsx(file, clazz);
		// }
		//
		// return null;

		return readXlsx(file, clazz);
	}

	@SuppressWarnings("deprecation")
	public static <T> List<T> readXlsx(MultipartFile file, Class<?> clazz)
			throws IllegalArgumentException, IllegalAccessException {
		InputStream input = null;
		List<T> list = null;

		try {
			input = file.getInputStream();
			// 创建文档
			XSSFWorkbook wb = new XSSFWorkbook(input);
			// 只读取sheet第一页
			XSSFSheet xssfSheet = wb.getSheetAt(0);
			if (xssfSheet == null) {
				return Collections.emptyList();
			}
			int rowCount = xssfSheet.getLastRowNum();
			list = new ArrayList<T>(rowCount - 1);

			Field[] fields = getFieldsBySort(clazz);

			// 读取Row,从第二行开始
			for (int i = 1; i <= rowCount; i++) {
				XSSFRow xssfRow = xssfSheet.getRow(i);
				if (xssfRow != null) {
					int columns = xssfRow.getLastCellNum();

					@SuppressWarnings("unchecked")
					T a = (T) createInstance(clazz);

					// 读取列，从第一列开始
					for (int c = 0; c < columns; c++) {
						XSSFCell cell = xssfRow.getCell(c);

						fields[c].setAccessible(true);
						if (cell == null) {
							fields[c].set(a, STRING_EMPTY);
							continue;
						}
						Class<?> fieldClazz = fields[c].getType();
						if (fieldClazz == String.class) {
							fields[c].set(a, cell.toString().replace("\n", "").replace("\t", "").trim());
						} else if (fieldClazz == Integer.class) {
							fields[c].set(a, cell.toString().length() == 0 ? null
									: Integer.valueOf(cell.toString().split("\\.")[0]));
						} else if (fieldClazz == BigDecimal.class) {
							fields[c].set(a, cell.toString().length() == 0 ? null
									: new BigDecimal(cell.toString()));
						} 
					}

					list.add(a);
				}
			}
			return list;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;

	}

	public static <T> T createInstance(Class<T> cls) {
		T obj = null;
		try {
			obj = cls.newInstance();
		} catch (Exception e) {
			obj = null;
		}
		return obj;
	}

	/**
	 * read the Excel 2003-2007 .xls
	 * 
	 * @param file
	 * @return
	 */
	public static List<String[]> readXls(MultipartFile file) {
		List<String[]> list = null;
		// IO流读取文件
		InputStream input = null;
		try {
			input = file.getInputStream();
			// 创建文档
			HSSFWorkbook wb = new HSSFWorkbook(input);
			// 读取sheet(页)
			HSSFSheet hssfSheet = wb.getSheetAt(0);
			if (hssfSheet == null) {
				return list;
			}
			int rowCount = hssfSheet.getLastRowNum();
			list = new ArrayList<String[]>(rowCount - 1);
			// 读取Row,从第二行开始
			for (int i = 1; i <= rowCount; i++) {
				HSSFRow hssfRow = hssfSheet.getRow(i);
				if (hssfRow != null) {
					int colums = hssfRow.getLastCellNum();
					String[] rowArray = new String[colums];
					// 读取列，从第一列开始
					for (int c = 0; c < colums; c++) {
						HSSFCell cell = hssfRow.getCell(c);
						if (cell == null) {
							rowArray[c] = STRING_EMPTY;
							continue;
						}
						// rowArray[c] = getHValue(cell).trim();
						rowArray[c] = cell.toString();
					}
					list.add(rowArray);
				}
			}
			return list;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	private static Field[] getFieldsBySort(Class<?> clazz) {

		Field[] fields = clazz.getDeclaredFields();
		List<Field> list = new ArrayList<Field>();
		List<Integer> annotationList = new LinkedList<Integer>();
		for (Field field : fields) {
			ExportExcelAnnotation ee = field.getAnnotation(ExportExcelAnnotation.class);
			if (ee != null) {
				list.add(field);
				annotationList.add(ee.index());
			}
		}
		Collections.sort(annotationList);
		Field[] fields2 = new Field[list.size()];

		for (int i = 0; i < annotationList.size(); i++) {
			for (int j = 0; j < list.size(); j++) {
				ExportExcelAnnotation ee = list.get(j).getAnnotation(ExportExcelAnnotation.class);
				if (annotationList.get(i) == ee.index()) {
					fields2[i] = list.get(j);
				}
			}
		}
		return fields2;
	}

}